package wen;


import org.apache.commons.io.IOUtils;
import wen.utils.StringUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

class Task implements Runnable {

    private final URL url;
    private final String fileName;
    private final String fileLocation;

    public Task(String urlString, String fileName, String fileLocation) throws MalformedURLException {
        this.fileLocation = fileLocation;
        StringUtils su = new StringUtils();
        this.url = new URL(su.urlLegalize(urlString));
        this.fileName = su.fileNameLegalize(fileName, urlString);
    }


    @Override
    public void run() {

        try {
            writeFile(download());
        } catch (Exception e) {
            System.out.println("[ERROR] Failed to download file " + fileName + ".");
            e.printStackTrace();
        }

    }

    /**
     * 检查目录是否存在否则创建
     */
    private File checkDirectory() throws Exception {
        File pathF = new File(fileLocation);
        if (!pathF.exists()) {
            if (pathF.mkdirs()) System.out.println("[DOWNLOADER] Directory " + fileLocation + " created.");
            else throw new Exception();
        }
        File file=new File(pathF,fileName);
        if(file.exists()){
            System.out.println("[DOWNLOADER] The file "+fileName+" already exists.");
            return null;
        }
        return file;
    }

    private byte[] download() throws IOException {
        int timeOut = 100000;
        final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36";
        final long MAX_DOWNLOAD_SIZE = 40L * 1024 * 1024;
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        httpURLConnection.setConnectTimeout(timeOut);
        httpURLConnection.setReadTimeout(timeOut);
        httpURLConnection.setRequestProperty("User-Agent", USER_AGENT);
        long start = System.currentTimeMillis();

        //check if the content is too long
        int len = httpURLConnection.getContentLength();
        if (len >= MAX_DOWNLOAD_SIZE) {
            System.out.println("[DOWNLOADER ERROR] The content to download is too long!");
        }
        if (len == -1) {
            InputStream in = httpURLConnection.getInputStream();
            return IOUtils.toByteArray(httpURLConnection.getInputStream());
        }
        byte[] data = new byte[len];
        byte[] buffer = new byte[4096 * 2];
        int count = 0, sum = 0;
        try (InputStream in = httpURLConnection.getInputStream()) {
            while ((count = in.read(buffer)) > 0) {
                long elapse = System.currentTimeMillis() - start;
                if (elapse >= timeOut) {
                    data = null;
                    break;
                }
                System.arraycopy(buffer, 0, data, sum, count);
                sum += count;
            }
        }
        httpURLConnection.disconnect();
        return data;
    }

    private void writeFile(byte[] data) throws Exception {
        File file = checkDirectory();
        if(file==null) {
            System.out.println("[DOWNLOADER] The download Task has been skipped.");
            return;
        }
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        bufferedOutputStream.write(data);
        bufferedOutputStream.close();
        fileOutputStream.close();
    }

}
